//
// Created by 52499 on 2022/8/26.
//

#include "ResultJudge.h"
#include "algorithm"

bool ResultJudge::royalStraightFlush(vector<Poker> v) {
    if (!flush(v)) return false;
    bool b2 = v[0].getPoint() == 8 && v[1].getPoint() == 9 && v[2].getPoint() == 10 && v[3].getPoint() == 11 &&
              v[4].getPoint() == 12;
    return b2;
}

int ResultJudge::judge(vector<Poker> v) {
    if (royalStraightFlush(v))return 9;
    else if (straightFlush(v)) return 8;
    else if (fourOfAKind(v)) return 7;
    else if (fullHouse(v)) return 6;
    else if (flush(v)) return 5;
    else if (straight(v)) return 4;
    else if (threeOfAKind(v)) return 3;
    else if (twoPair(v)) return 2;
    else if (onePair(v)) return 1;
    else return 0;
}

bool ResultJudge::straightFlush(vector<Poker> v) {
    return flush(v) && straight(v);
}

bool ResultJudge::fourOfAKind(vector<Poker> v) {
    vector<int> vi = toInt(v);
    int c = count(vi.begin(), vi.end(), vi[0]);
    if (c == 4) return true;
    else return count(vi.begin(), vi.end(), vi[1]) == 4;
}

bool ResultJudge::fullHouse(vector<Poker> v) {
    vector<int> vi = toInt(v);
    for (int i = 0; i < 5; i++) {
        int c = count(vi.begin(), vi.end(), vi[i]);
        if (c != 3 && c != 2) return false;
    }
    return true;
}

bool ResultJudge::flush(vector<Poker> v) {
    return v[0].getType() == v[1].getType() &&
           v[1].getType() == v[2].getType() &&
           v[2].getType() == v[3].getType() &&
           v[3].getType() == v[4].getType();
}

bool ResultJudge::straight(vector<Poker> v) {
    return v[0].getPoint() + 1 == v[1].getPoint() && v[1].getPoint() + 1 == v[2].getPoint() &&
           v[2].getPoint() + 1 == v[3].getPoint() && v[3].getPoint() + 1 == v[4].getPoint();
}

bool ResultJudge::threeOfAKind(vector<Poker> v) {
    vector<int> vi = toInt(v);
    int three = 0;
    for (int i = 0; i < 5; i++) {
        int c = count(vi.begin(), vi.end(), vi[i]);
        if (c != 3 && c != 1)
            return false;
        if (c == 3) three++;
    }
    return three == 3;
}

bool ResultJudge::twoPair(vector<Poker> v) {
    vector<int> vi = toInt(v);
    int pairs = 0;
    for (int i = 0; i < 5; i++) {
        int c = count(vi.begin(), vi.end(), vi[i]);
        if (c == 2) pairs++;
    }
    return pairs == 4;
}

bool ResultJudge::onePair(vector<Poker> v) {
    vector<int> vi = toInt(v);
    int pairs = 0;
    for (int i = 0; i < 5; i++) {
        int c = count(vi.begin(), vi.end(), vi[i]);
        if (c == 2) pairs++;
    }
    return pairs == 2;
}

vector<int> ResultJudge::toInt(vector<Poker> v) {
    vector<int> vi;
    for (vector<Poker>::iterator it = v.begin(); it != v.end(); it++) {
        vi.push_back(it->getPoint());
    }
    return vi;
}
